package math;

import static math.ExpressionBuilder.cos;
import static math.ExpressionBuilder.mult;

public class Sin implements ArithmeticExpression {

  private ArithmeticExpression argument;

  public ArithmeticExpression getArgument() {
    return argument;
  }
  
  private Sin(ArithmeticExpression expression){
    this.argument = expression;
  }
  
  public static Sin createSin(ArithmeticExpression arg){
    return new Sin(arg);
  }
  
  @Override
  public boolean isOne() {
    return false;
  }

  @Override
  public boolean isZero() {
    return argument.isZero();
  }

  @Override
  public boolean equals(Object obj) {
    if (obj instanceof Sin) {
      Sin sin2 = (Sin) obj;
      return sin2.argument.equals(argument);
    } else
      return false;
  }

  @Override
  public ArithmeticExpression derivate(Variable var) {
    return mult(argument.derivate(var), cos(argument));
  }

  @Override
  public int hashCode() {
    return argument.hashCode() * PI.PI.hashCode();
  }

  @Override
  public int getPriority() {
    return 2;
  }

  @Override
  public ArithmeticExpression simplify() {
    return this;
  }
  
  @Override
  public int countMembers() {
    return 1 + argument.countMembers();
  }

  @Override
  public String toString() {
    return "sin(" + argument.toString() + ")";
  }

  @Override
  public boolean matches(Expression expr) {
    if (expr instanceof Sin) {
      Sin eSin = (Sin) expr;
      return argument.matches(eSin.getArgument());
    } else
      return false;
  }

  @Override
  public <R> R accept(ExpressionVisitor<R> visitor) {
    return visitor.visitSin(this);
  }
}